home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc International / Development / TSMTEsample⁄1.1 / Source / SamplePartUtils.cpp < prev    next >
Encoding:
Text File  |  1996-11-14  |  23.2 KB  |  843 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        SamplePartUtils.cpp
  3.  
  4.     Contains:    SamplePart utility functions & classes
  5.  
  6.     Written by:    Steve Smith
  7.  
  8.     Copyright:    © 1994,95 by Apple Computer, Inc., all rights reserved.
  9. */
  10.  
  11. // -- Compiler/Preprocessor Switches --
  12.  
  13. #ifndef _COMPILERDEFS_
  14. #include "CompDefs.h"
  15. #endif
  16.  
  17. // -- OpenDoc Utilities --
  18.  
  19. #ifndef _EXCEPT_
  20. // Exceptions define several important macros (ie. CHECKENV)
  21. // which are used in the SOM method dispatch glue. If Except.h
  22. // is not included early enough, exceptions may not be thrown
  23. // correctly when returning from a SOM method with the "ev" parameter set.
  24. #include <Except.h>
  25. #endif
  26.  
  27. // --- SamplePart Includes ---
  28.  
  29. #ifndef _SAMPLEPARTUTILS_
  30. #include "SamplePartUtils.h"
  31. #endif
  32.  
  33. #ifndef _SAMPLEPARTDEF_
  34. #include "SamplePartDef.h"
  35. #endif
  36.  
  37. // --- OpenDoc Includes ---
  38.  
  39. #ifndef _ODTYPES_
  40. #include <ODTypes.h>
  41. #endif
  42.  
  43. #ifndef SOM_Module_OpenDoc_StdProps_defined
  44. #include <StdProps.xh>
  45. #endif
  46.  
  47. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  48. #include <StdTypes.xh>
  49. #endif
  50.  
  51. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  52. #include <StdDefs.xh>
  53. #endif
  54.  
  55. #ifndef SOM_ODFrame_xh
  56. #include <Frame.xh>
  57. #endif
  58.  
  59. #ifndef SOM_ODSession_xh
  60. #include <ODSessn.xh>
  61. #endif
  62.  
  63. #ifndef SOM_ODDraft_xh
  64. #include <Draft.xh>
  65. #endif
  66.  
  67. #ifndef SOM_ODStorageUnit_xh
  68. #include <StorageU.xh>
  69. #endif
  70.  
  71. #ifndef SOM_ODStorageUnitView_xh
  72. #include <SUView.xh>
  73. #endif
  74.  
  75. #ifndef SOM_ODDocument_xh
  76. #include <Document.xh>
  77. #endif
  78.  
  79. #ifndef SOM_ODContainer_xh
  80. #include <ODCtr.xh>
  81. #endif
  82.  
  83. #ifndef SOM_ODNameSpaceManager_xh
  84. #include <NmSpcMg.xh>
  85. #endif
  86.  
  87. #ifndef SOM_ODValueNameSpace_xh
  88. #include <ValueNS.xh>
  89. #endif
  90.  
  91. #ifndef SOM_ODWindowState_xh
  92. #include <WinStat.xh>
  93. #endif
  94.  
  95. // -- OpenDoc Utilities --
  96.  
  97. #ifndef _BNDNSUTL_
  98. #include <BndNSUtl.h>
  99. #endif
  100.  
  101. #ifndef _DOCUTILS_
  102. #include <DocUtils.h>
  103. #endif
  104.  
  105. #ifndef _ISOSTR_
  106. #include <ISOStr.h>
  107. #endif
  108.  
  109. #ifndef _ODDEBUG_
  110. #include <ODDebug.h>
  111. #endif
  112.  
  113. #ifndef _STDTYPIO_
  114. #include <StdTypIO.h>
  115. #endif
  116.  
  117. #ifndef _STORUTIL_    
  118. #include <StorUtil.h>
  119. #endif
  120.  
  121. #ifndef _TEMPOBJ_
  122. #include <TempObj.h>
  123. #endif
  124.  
  125. #ifndef _TEMPITER_
  126. #include <TempIter.h>
  127. #endif
  128.  
  129. #ifndef _USERSRCM_
  130. #include <UseRsrcM.h>
  131. #endif
  132.  
  133. // --- Macintosh Includes ---
  134.  
  135. #ifndef __RESOURCES__
  136. #include <Resources.h>
  137. #endif
  138.  
  139. #ifndef __GXMATH__
  140. #include <GXMath.h>
  141. #endif
  142.  
  143. #ifndef __SCRIPT__
  144. #include <Script.h>
  145. #endif
  146.  
  147. #ifndef __TEXTUTILS__
  148. #include <TextUtils.h>
  149. #endif
  150.  
  151.  
  152. #pragma segment SamplePartUtilities
  153.  
  154.  
  155. //====================================================================
  156. // Utility Functions
  157. //====================================================================
  158.  
  159. //--------------------------------------------------------------------
  160. // GetPartName
  161. //--------------------------------------------------------------------
  162.  
  163. ODIText* GetPartName(Environment* ev, ODPart* part, ODType category)
  164. {
  165.     ASSERT(part != kODNULL, kODErrIllegalNullPartInput);
  166.  
  167.     // Get the root part of the document.
  168.     ODDraft* draft = ODGetDraft(ev,part);
  169.     TempODPart rootPart = ODAcquireRootPartOfDraft(ev, draft);
  170.     
  171.     // Get the part name.
  172.     // If we can't get a valid name for the part, we generate one using
  173.     // the user visible category name of the part's category.
  174.     TempODIText partName = ODGetITextProp(ev, part->GetStorageUnit(ev), 
  175.                                          kODPropName, kODMacIText, kODNULL);
  176.     
  177.     // If the part is the root of the document, return the name of the file.
  178.     if ( ODObjectsAreEqual(ev, part, rootPart) )
  179.     {
  180.         ODContainer* container = draft->GetDocument(ev)->GetContainer(ev);
  181.         TempPlatformFile file = GetPlatformFileFromContainer(ev, container);
  182.  
  183.         TempODIText fileName = file->GetName();
  184.         
  185.         // Test the file name against the part name. If the two are equivalent
  186.         // (not equal), then use the part name.
  187.         if ( !NamesAreEquivalent(ev, fileName, partName) )
  188.         {
  189.             // If the names are different, return the file name.
  190.             // (This code transfers the ODIText object to the partName tempobj)
  191.             DisposeIText(partName.DontDelete());
  192.             partName = fileName.DontDelete();
  193.         }
  194.     }
  195.     else
  196.     {
  197.         if ( (partName == kODNULL) || (GetITextStringLength(partName) == 0) )
  198.         {
  199.             ODIText* categoryName;
  200.             ODNameSpaceManager* nsMgr = ODGetSession(ev,part)->GetNameSpaceManager(ev);
  201.             
  202.             // Get the category string from the category name space.
  203.             if ( GetUserCatFromCat(nsMgr, category, &categoryName) )
  204.             {
  205.                 // If we successfully retrieved the category user string, return it.
  206.                 // (This code transfers the ODIText object to the partName tempobj)
  207.                 DisposeIText(partName.DontDelete());
  208.                 partName = categoryName;
  209.             }
  210.             else
  211.             {
  212.     #if ODDebug
  213.                 // This should never happen. Check NMAP for errors.
  214.                 DebugStr("\pCategory NMAP bad, or Preferences corrupted.");
  215.     #else
  216.                 THROW(kODErrInvalidNSType);
  217.     #endif
  218.             }
  219.         }
  220.     }
  221.     
  222.     return partName.DontDelete();
  223. }
  224.  
  225. //--------------------------------------------------------------------
  226. // NamesAreEquivalent
  227. //--------------------------------------------------------------------
  228.  
  229. ODBoolean NamesAreEquivalent(Environment* ev, ODIText* fileName,
  230.                                         ODIText* partName)
  231. {
  232.     Str255 fileStr;
  233.     Str255 partStr;
  234.     
  235.     // If the strings are in different languages, we're done.
  236.     if ( (GetITextScriptCode(fileName) != GetITextScriptCode(partName)) ||
  237.             GetITextLangCode(fileName) != GetITextLangCode(partName) )
  238.         return kODFalse;
  239.     
  240.     GetITextPString(fileName, fileStr);
  241.     GetITextPString(partName, partStr);
  242.  
  243.     // If the string lengths are different, we're done.
  244.     if ( fileStr[0] != partStr[0] )
  245.         return kODFalse;
  246.  
  247.     // Return the Toolbox string equivalence test.
  248.     return EqualString(fileStr,partStr,kODTrue,kODTrue);
  249. }
  250.  
  251. //--------------------------------------------------------------------
  252. // GetScriptLanguageFromRegion
  253. //--------------------------------------------------------------------
  254. void GetScriptLanguageFromRegion(long region, ODScriptCode* script, ODLangCode* language)
  255. {
  256.     #define    anyNumber    1
  257.     
  258.     typedef    struct {
  259.         short        itlmVersion;
  260.         short        itlmFormat;
  261.         short        itlmRunTables;
  262.         long        itlmScriptDataOffset;            /* For script -> language */
  263.         long        itlmScriptDataLength;
  264.         long        itlmLanguageDataOffset;            /* For language -> script */
  265.         long        itlmLanguageDataLength;
  266.         long        itlmRegionDataOffset;            /* For region -> language */
  267.         long        itlmRegionDataLength;
  268.         long        itlmData[1];
  269.     } itlmRecord, *itlmRecordPointer, **itlmRecordHandle;
  270.     
  271.     typedef struct {
  272.         short    source;
  273.         short    dest;
  274.     } CodeAssocRecord;
  275.     
  276.     typedef struct {
  277.         short                    maxCode;
  278.         short                    defaultCode;
  279.         short                    numberOfEntry;
  280.         CodeAssocRecord            data[anyNumber];
  281.     } CodeAssocData;
  282.     
  283.     itlmRecordHandle        itlmHandle;
  284.     CodeAssocData            *codeData;
  285.     short                    assocCount;
  286.     CodeAssocRecord            *codeToCode;
  287.     
  288.     itlmHandle = (itlmRecordHandle)GetResource( 'itlm', 0);
  289.  
  290.     codeData    = (CodeAssocData *)( ((char *)*itlmHandle) + (*itlmHandle)->itlmRegionDataOffset);
  291.     codeToCode    = codeData->data;
  292.     *language    = codeData->defaultCode;
  293.  
  294.     for( assocCount = 0; assocCount < codeData->numberOfEntry; assocCount++)
  295.     {
  296.         if ( codeToCode[assocCount].source == region )
  297.         {
  298.             *language    = codeToCode[assocCount].dest;
  299.             break;
  300.         }
  301.     }
  302.  
  303.     codeData    = (CodeAssocData *)( ((char *)*itlmHandle) + (*itlmHandle)->itlmLanguageDataOffset);
  304.     codeToCode    = codeData->data;
  305.     *script        = codeData->defaultCode;
  306.  
  307.     for( assocCount = 0; assocCount < codeData->numberOfEntry; assocCount++)
  308.     {
  309.         if ( codeToCode[assocCount].source == *language )
  310.         {
  311.             *script        = codeToCode[assocCount].dest;
  312.             break;
  313.         }
  314.     }
  315. }
  316.  
  317. //--------------------------------------------------------------------
  318. // GetEditorScriptLanguage
  319. //--------------------------------------------------------------------
  320.  
  321. void GetEditorScriptLanguage(Environment* ev, ODScriptCode* script,
  322.                                         ODLangCode* language)
  323. {
  324.     long region;
  325.     
  326.     ODSLong rfRef;
  327.     rfRef = BeginUsingLibraryResources();
  328.     {
  329.         Handle versHdl = Get1Resource('vers', 1);
  330.         
  331.         // Get the region code of the editor, otherwise use the
  332.         // region code the of the primary system script.
  333.         
  334.         if ( versHdl )
  335.         {
  336.             region = (long)(*(VersRecHndl)versHdl)->countryCode;
  337.             ReleaseResource(versHdl);
  338.         }
  339.         else
  340.         {
  341.             region = GetScriptManagerVariable(smRegionCode);
  342.         }
  343.         
  344.         // Spanish & Japanese are not actually supported by the editor.
  345.         // They are provided as examples of how to add recognition of
  346.         // additional regions (see Script.h for region codes).
  347.         ::GetScriptLanguageFromRegion(region, script, language);
  348.         
  349.     }
  350.     EndUsingLibraryResources(rfRef);
  351. }
  352.  
  353. //--------------------------------------------------------------------
  354. // FixedToIntRect
  355. //--------------------------------------------------------------------
  356.  
  357. void FixedToIntRect(ODRect& fixedRect, Rect& intRect)
  358. {
  359.     intRect.top        = FixedToInt(fixedRect.top);
  360.     intRect.left    = FixedToInt(fixedRect.left);
  361.     intRect.bottom    = FixedToInt(fixedRect.bottom);
  362.     intRect.right    = FixedToInt(fixedRect.right);
  363. }
  364.  
  365. //--------------------------------------------------------------------
  366. // IntToFixedRect
  367. //--------------------------------------------------------------------
  368.  
  369. void IntToFixedRect(Rect& intRect, ODRect& fixedRect)
  370. {
  371.     fixedRect.left        = ff(intRect.left);
  372.     fixedRect.top        = ff(intRect.top);
  373.     fixedRect.right        = ff(intRect.right);
  374.     fixedRect.bottom    = ff(intRect.bottom);
  375. }
  376.  
  377. //--------------------------------------------------------------------
  378. // LoadThumbnail
  379. //--------------------------------------------------------------------
  380.  
  381. void LoadThumbnail(Environment* ev, Handle* thumbnail)
  382. {
  383.     if ( *thumbnail ) return;
  384.     
  385.     ODSLong rfRef;
  386.     rfRef = BeginUsingLibraryResources();
  387.     {
  388.         *thumbnail = (Handle) GetPicture(kThumbnailPicture);
  389.     }
  390.     EndUsingLibraryResources(rfRef);
  391. }
  392.  
  393. //--------------------------------------------------------------------
  394. // TilePartWindow
  395. //--------------------------------------------------------------------
  396.  
  397. Rect TilePartWindow(Environment* ev, Rect* facetBounds, Rect* partWindowBounds)
  398. {
  399.     const short    kWindowTilingConst    = 20;
  400.     const short kLeftToRight        = 0;
  401.     const short kRightToLeft        = -1;
  402.     
  403.     short direction;
  404.     
  405.     // Get the direction for the primary script system running on this machine.
  406.     // (Right-to-Left or Left-to-Right)
  407.     direction = GetSysDirection();
  408.     
  409.     // The child window should be tiled from the topLeft corner of the 
  410.     // active facet whose frame is being opened.
  411.     if ( direction == kLeftToRight )
  412.     {
  413.         // Position the window rect at the top/left corner of the facet.
  414.         OffsetRect(partWindowBounds, facetBounds->left, facetBounds->top);
  415.         // Now tile the window rect down and to the right.
  416.         OffsetRect(partWindowBounds, kWindowTilingConst, kWindowTilingConst);
  417.     }
  418.     // The child window should be tiled from the topRight corner of the 
  419.     // active facet whose frame is being opened.
  420.     else if ( direction == kRightToLeft )
  421.     {
  422.         // Position the window rect at the top/right corner of the facet.
  423.         OffsetRect(partWindowBounds, (partWindowBounds->right - facetBounds->right),
  424.                     facetBounds->top);
  425.         // Now tile the window rect down and to the left.
  426.         OffsetRect(partWindowBounds, -kWindowTilingConst, kWindowTilingConst);
  427.     }
  428.     
  429.     return *partWindowBounds;
  430. }
  431.  
  432. //--------------------------------------------------------------------
  433. // CountFacets
  434. //--------------------------------------------------------------------
  435.  
  436. ODUShort CountFramesFacets(Environment* ev, ODFrame* frame)
  437. {
  438.     ODUShort facetCount = 0;
  439.     ODFacet* facet;
  440.     
  441.     TempODFrameFacetIterator ffiter(ev, frame);
  442.     facet = ffiter.First();
  443.     while ( ffiter.IsNotComplete() )
  444.     {
  445.         facetCount++;
  446.         facet = ffiter.Next();
  447.     }
  448.     
  449.     return facetCount;
  450. }
  451.  
  452. //=========================================================================
  453. // CFrameProxy
  454. //=========================================================================
  455.  
  456. //-------------------------------------------------------------------------
  457. // CFrameProxy::SetFrame
  458. //
  459. // The code will not affect the proxy fields unless it can
  460. // successfully acquire the incoming frame, its id, and
  461. // the draft the frame lives in. If something goes wrong,
  462. // the proxy remains unchanged.
  463. //-------------------------------------------------------------------------
  464.  
  465. void CFrameProxy::SetFrame(Environment* ev, ODFrame* frame)
  466. {
  467.     ASSERT(frame!=kODNULL, kODErrIllegalNullFrameInput);
  468.     
  469.     ODID id;
  470.     ODDraft* draft;
  471.     
  472.     // Using the temp object will cleanup the incoming
  473.     // frame's refcount if something goes wrong.
  474.     frame->Acquire(ev);
  475.     TempODFrame tFrame = frame;
  476.     
  477.     // Perform all the operations that can fail, first.
  478.     TempODPart tPart = frame->AcquirePart(ev);
  479.     id = frame->GetID(ev);
  480.     draft = ODGetDraft(ev, tPart);
  481.     ODReleaseObject(ev, fFrame);
  482.  
  483.     // If all went well, set the proxy fields.
  484.     fFrame = tFrame.DontRelease();
  485.     fID = id;
  486.     fDraft = draft;
  487. }
  488.  
  489. //-------------------------------------------------------------------------
  490. // CFrameProxy::GetFrame
  491. //-------------------------------------------------------------------------
  492.  
  493. ODFrame* CFrameProxy::GetFrame(Environment* ev)
  494. {
  495.     if ( fFrame == kODNULL )
  496.     {
  497.         TRY
  498.             TempODFrame frame = fDraft->AcquireFrame(ev, fID);
  499.             this->SetFrame(ev,frame);
  500.         CATCH_ALL
  501.             fFrame = kODNULL;
  502.             fID = kODNULLID;
  503.         ENDTRY
  504.     }
  505.     return fFrame;
  506. }
  507.  
  508. //-------------------------------------------------------------------------
  509. // CFrameProxy::FrameIsLoaded
  510. //-------------------------------------------------------------------------
  511.  
  512. ODBoolean CFrameProxy::FrameIsLoaded(Environment* ev)
  513. {
  514.     ODBoolean loaded = (fFrame != kODNULL ||
  515.                         fDraft->IsValidID(ev, fID));
  516.     return loaded;
  517. }
  518.  
  519. //-------------------------------------------------------------------------
  520. // CFrameProxy::Purge
  521. //-------------------------------------------------------------------------
  522.  
  523. void CFrameProxy::Purge(Environment* ev)
  524. {
  525.     if ( fFrame != kODNULL )
  526.     {
  527.         fID = fFrame->GetID(ev);
  528.         ODReleaseObject(ev, fFrame);
  529.     }
  530. }
  531.  
  532. //=========================================================================
  533. // CFrameInfo
  534. //=========================================================================
  535.  
  536. //-------------------------------------------------------------------------
  537. // CFrameInfo::CFrameInfo
  538. //-------------------------------------------------------------------------
  539.  
  540. CFrameInfo::CFrameInfo(ODSession* session)
  541. {
  542.     fSession = session;
  543.     fFrameActive = kODFalse;
  544.     fFrameReactivate  = kODFalse;
  545.     fShouldDisposeWindow = kODFalse;
  546.     fActiveFacet = kODNULL;
  547.     fSourceFrame = kODNULL;
  548.     fDependentFrame = kODNULL;
  549.     fPartWindowID = kODNULLID; 
  550. }
  551.  
  552. //-------------------------------------------------------------------------
  553. // CFrameInfo::~CFrameInfo
  554. //-------------------------------------------------------------------------
  555.  
  556. CFrameInfo::~CFrameInfo()
  557. {
  558.     // Deleting the proxies will release the encapsulated frames.
  559.     ODDeleteObject(fDependentFrame);
  560.     ODDeleteObject(fSourceFrame);
  561. }
  562.  
  563. //-------------------------------------------------------------------------
  564. // CFrameInfo::Externalize
  565. //-------------------------------------------------------------------------
  566.  
  567. void CFrameInfo::Externalize(Environment* ev, ODStorageUnitView* storageUnitView)
  568. {
  569.     // This method assumes that OpenDoc has passed us a storageUnitView
  570.     // that is focused to a property, but no particular value.
  571.     
  572.     ODStorageUnit* storageUnit = storageUnitView->GetStorageUnit(ev);
  573.  
  574.     this->CleanseFrameInfoProperty(ev, storageUnit);
  575.     this->ExternalizeFrameInfo(ev, storageUnit, kODNULLKey, kODNULL);
  576. }
  577.  
  578. //-------------------------------------------------------------------------
  579. // CFrameInfo::CleanseFrameInfoProperty
  580. //-------------------------------------------------------------------------
  581.  
  582. void CFrameInfo::CleanseFrameInfoProperty(Environment* ev, ODStorageUnit* storageUnit)
  583. {
  584.     ODULong numValues;
  585.     ODULong index;
  586.         
  587.     numValues = storageUnit->CountValues(ev);
  588.     
  589.     for (index = numValues; index >= 1; index--)
  590.     {
  591.         // Index, from 1 to n, through the values.
  592.         storageUnit->Focus(ev, kODNULL, kODPosSame, 
  593.                                 kODNULL, index, kODPosUndefined);
  594.                                 
  595.         // Get the ISO type name for the value. The temp object
  596.         // will automatically delete the returned value when this
  597.         // scope is exited.
  598.         TempODValueType value = storageUnit->GetType(ev);
  599.         
  600.         // If the value type is not one we support, remove it.
  601.         if ( ODISOStrCompare(value, kSamplePartInfo) != 0 )
  602.             storageUnit->Remove(ev);
  603.     }
  604. }
  605.  
  606. //-------------------------------------------------------------------------
  607. // CFrameInfo::ExternalizeFrameInfo
  608. //-------------------------------------------------------------------------
  609.  
  610. void CFrameInfo::ExternalizeFrameInfo(Environment* ev, ODStorageUnit* storageUnit,
  611.                                         ODDraftKey key, ODFrame* scopeFrame)
  612. {
  613.     // This method behaves much the same way as the SamplePart::ExternalizeStateInfo
  614.     // method.
  615.     
  616.     if ( storageUnit->Exists(ev, kODNULL, kSamplePartInfo, 0) )
  617.     {
  618.         // Persistent object references are stored in a side table, rather than
  619.         // in the property/value stream. Thus, deleting the contents of a value
  620.         // will not "delete" the references previously written to that value. To
  621.         // completely "delete" all references written to the value, we must
  622.         // remove the value and add it back.
  623.  
  624.         storageUnit->Focus(ev, kODNULL, kODPosSame, kSamplePartInfo, 0, kODPosUndefined);
  625.         storageUnit->Remove(ev);
  626.     }
  627.  
  628.     // Add a value to write the data into.
  629.     storageUnit->AddValue(ev, kSamplePartInfo);
  630.     
  631.     // Write a weak reference to our source frame.
  632.     {
  633.         ODStorageUnitRef weakRef = {0,0,0,0};
  634.         
  635.         if ( fSourceFrame )
  636.         {
  637.             ODID        frameID = fSourceFrame->GetID();
  638.             ODID        scopeFrameID = ( scopeFrame ? scopeFrame->GetID(ev) : kODNULLID );
  639.             ODDraft*    fromDraft = fSourceFrame->GetDraft();
  640.     
  641.             // If a draft key exists, then we are being cloned to another draft.
  642.             // We must "weak" clone our display frame and reference the cloned
  643.             // frame. The part re-uses the frameID variable so there aren't two
  644.             // different GetWeakStorageUnitRef calls.
  645.             if ( key )
  646.                 frameID = fromDraft->WeakClone(ev, key, frameID, kODNULLID, scopeFrameID);
  647.             
  648.             // Write out weak references to each of the part's display frames.
  649.             storageUnit->GetWeakStorageUnitRef(ev, frameID, weakRef);
  650.         }
  651.         StorageUnitSetValue(storageUnit, ev, sizeof(ODStorageUnitRef), (ODPtr)&weakRef);
  652.     }
  653.     
  654.     // Write a weak reference to our dependent frame.
  655.     {
  656.         ODStorageUnitRef weakRef = {0,0,0,0};
  657.         
  658.         if ( fDependentFrame )
  659.         {
  660.             ODID        frameID = fDependentFrame->GetID();
  661.             ODID        scopeFrameID = ( scopeFrame ? scopeFrame->GetID(ev) : kODNULLID );
  662.             ODDraft*    fromDraft = fDependentFrame->GetDraft();
  663.     
  664.             // If a draft key exists, then we are being cloned to another draft.
  665.             // We must "weak" clone our display frame and reference the cloned
  666.             // frame. The part re-uses the frameID variable so there aren't two
  667.             // different GetWeakStorageUnitRef calls.
  668.             if ( key )
  669.                 frameID = fromDraft->WeakClone(ev, key, frameID, kODNULLID, scopeFrameID);
  670.             
  671.             // Write out weak references to each of the part's display frames.
  672.             storageUnit->GetWeakStorageUnitRef(ev, frameID, weakRef);
  673.         }
  674.         StorageUnitSetValue(storageUnit, ev, sizeof(ODStorageUnitRef), (ODPtr)&weakRef);
  675.     }
  676. }
  677.  
  678. //-------------------------------------------------------------------------
  679. // CFrameInfo::CloneInto
  680. //-------------------------------------------------------------------------
  681.  
  682. void CFrameInfo::CloneInto(Environment *ev, ODDraftKey key,
  683.                             ODStorageUnitView* storageUnitView, ODFrame* scopeFrame)
  684. {
  685.     // This method assumes that OpenDoc has passed us a storageUnitView
  686.     // that is focused to a property, but no particular value.
  687.     
  688.     ODStorageUnit* storageUnit = storageUnitView->GetStorageUnit(ev);
  689.  
  690.     if ( storageUnit->Exists(ev, kODNULL, kSamplePartInfo, 0) == kODFalse )
  691.     {
  692.         this->ExternalizeFrameInfo(ev, storageUnit, key, scopeFrame);
  693.     }
  694. }
  695.  
  696. //-------------------------------------------------------------------------
  697. // CFrameInfo::InitFromStorage
  698. //------------------------------------------------------------------------------
  699.  
  700. void CFrameInfo::InitFromStorage(Environment* ev, ODStorageUnitView* storageUnitView)
  701. {
  702.     // This method assumes that OpenDoc has passed us a storageUnitView
  703.     // that is focused to a property, but no particular value.
  704.     
  705.     ODStorageUnit* storageUnit = storageUnitView->GetStorageUnit(ev);
  706.  
  707.     if ( storageUnit->Exists(ev, kODNULL, kSamplePartInfo, 0) )
  708.     {
  709.         TRY
  710.             storageUnit->Focus(ev, kODNULL, kODPosSame,
  711.                                         kSamplePartInfo, 0 , kODPosUndefined);
  712.     
  713.             ODStorageUnitRef weakRef = {0,0,0,0};
  714.             StorageUnitGetValue(storageUnit, ev, sizeof(ODStorageUnitRef),
  715.                                 (ODPtr)&weakRef);
  716.             
  717.             if ( storageUnit->IsValidStorageUnitRef(ev, weakRef) )
  718.             {
  719.                 // Convert the reference into a runtime id.
  720.                 ODID frameID = storageUnit->GetIDFromStorageUnitRef(ev, weakRef);
  721.  
  722.                 // Create a proxy class to support the lazy internalization.
  723.                 CFrameProxy* proxy = new CFrameProxy;
  724.                 proxy->InitFrameProxy(frameID, ODGetDraft(ev,storageUnit));
  725.  
  726.                 // Store the proxy source frame.
  727.                 fSourceFrame = proxy;
  728.             }
  729.             
  730.         CATCH_ALL
  731.             ODDeleteObject(fSourceFrame);
  732.             fSourceFrame = kODNULL;
  733.         ENDTRY
  734.  
  735.         TRY
  736.             ODStorageUnitRef weakRef = {0,0,0,0};
  737.             StorageUnitGetValue(storageUnit, ev, sizeof(ODStorageUnitRef),
  738.                                 (ODPtr)&weakRef);
  739.             
  740.             if ( storageUnit->IsValidStorageUnitRef(ev, weakRef) )
  741.             {
  742.                 // Convert the reference into a runtime id.
  743.                 ODID frameID = storageUnit->GetIDFromStorageUnitRef(ev, weakRef);
  744.  
  745.                 // Create a proxy class to support the lazy internalization.
  746.                 CFrameProxy* proxy = new CFrameProxy;
  747.                 proxy->InitFrameProxy(frameID, ODGetDraft(ev,storageUnit));
  748.  
  749.                 // Store the proxy dependent frame.
  750.                 fDependentFrame = proxy;
  751.             }
  752.             
  753.         CATCH_ALL
  754.             ODDeleteObject(fDependentFrame);
  755.             fDependentFrame = kODNULL;
  756.         ENDTRY
  757.     }
  758. }
  759.  
  760. //-------------------------------------------------------------------------
  761. // CFrameInfo::SetSourceFrame
  762. //-------------------------------------------------------------------------
  763.  
  764. void CFrameInfo::SetSourceFrame(Environment* ev, ODFrame* frame)
  765. {
  766.     if ( frame != kODNULL )
  767.     {
  768.         // Create a proxy class to support the lazy internalization.
  769.         CFrameProxy* proxy = new CFrameProxy;
  770.         proxy->InitFrameProxy(ev,frame);
  771.         
  772.         // Store the proxy source frame after clearing the old one.
  773.         ODDeleteObject(fSourceFrame);
  774.         fSourceFrame = proxy;
  775.     }
  776. }
  777.  
  778. //-------------------------------------------------------------------------
  779. // CFrameInfo::ReleaseSourceFrame
  780. //-------------------------------------------------------------------------
  781.  
  782. void CFrameInfo::ReleaseSourceFrame(Environment* ev)
  783. {
  784.     ODDeleteObject(fSourceFrame);
  785. }
  786.  
  787. //-------------------------------------------------------------------------
  788. // CFrameInfo::SetDependentFrame
  789. //-------------------------------------------------------------------------
  790.  
  791. void CFrameInfo::SetDependentFrame(Environment* ev, ODFrame* frame)
  792. {
  793.     if ( frame != kODNULL )
  794.     {
  795.         // Create a proxy class to support the lazy internalization.
  796.         CFrameProxy* proxy = new CFrameProxy;
  797.         proxy->InitFrameProxy(ev,frame);
  798.         
  799.         // Store the proxy dependent frame after clearing the old one.
  800.         ODDeleteObject(fDependentFrame);
  801.         fDependentFrame = proxy;
  802.     }
  803. }
  804.  
  805. //-------------------------------------------------------------------------
  806. // CFrameInfo::ReleaseDependentFrame
  807. //-------------------------------------------------------------------------
  808.  
  809. void CFrameInfo::ReleaseDependentFrame(Environment* ev)
  810. {
  811.     ODDeleteObject(fDependentFrame);
  812. }
  813.  
  814. //-------------------------------------------------------------------------
  815. // CFrameInfo::GetPartWindow
  816. //-------------------------------------------------------------------------
  817.  
  818. ODWindow* CFrameInfo::AcquirePartWindow(Environment* ev)
  819. {
  820.     ODWindow* window = kODNULL;
  821.     
  822.     if ( fPartWindowID )
  823.     {
  824.         window = fSession->GetWindowState(ev)->AcquireWindow(ev,fPartWindowID);
  825.         if ( !window) fPartWindowID = kODNULLID;
  826.     }
  827.     
  828.     return window;
  829. }
  830.  
  831. //-------------------------------------------------------------------------
  832. // CFrameInfo::SetPartWindow
  833. //-------------------------------------------------------------------------
  834.  
  835. void CFrameInfo::SetPartWindow(Environment* ev, ODWindow* window)
  836. {
  837.     fPartWindowID = window ? window->GetID(ev) : kODNULLID;
  838. }
  839.  
  840.  
  841.  
  842.  
  843.